package service

import (
	"fmt"
	"go-chromedp-client/structs"
	"go-chromedp-client/util"
	"path"

	neturl "net/url"
	"strconv"
	"strings"

	"github.com/PuerkitoBio/goquery"

	"context"
	"encoding/json"
	"net/http"
	"os"

	"time"
)

func ComicMenuApi(w http.ResponseWriter, r *http.Request) {
	util.ApiHeader(&w)
	name := r.PostFormValue("name")
	url_post := r.PostFormValue("url")
	ua := r.PostFormValue("url")
	sort := r.PostFormValue("sort")
	prefix := r.PostFormValue("prefix")
	subpage := r.PostFormValue("subpage")
	submenu := r.PostFormValue("submenu")

	sublink := r.PostFormValue("sublink")
	start := r.PostFormValue("start")
	end := r.PostFormValue("end")

	fmt.Println(url_post, subpage)
	Api := &structs.API{}
	Api.Code = 1
	if url_post == "" {
		Api.Msg = "url缺失"
		api, _ := json.Marshal(Api)
		util.ApiWrite(&w, api)
		return
	}

	url_info, err := neturl.Parse(url_post)
	if err != nil {
		fmt.Println("url error 1:", err.Error())
		Api.Msg = "url error 1:" + err.Error()
		api, _ := json.Marshal(Api)
		util.ApiWrite(&w, api)
		return
	}
	start_num := 0
	end_num := 0

	if start != "" {
		start_num, err = strconv.Atoi(start)
		if err != nil {
			start_num = 0
		}
	}
	if end != "" {
		end_num, err = strconv.Atoi(end)
		if err != nil {
			end_num = 0
		}
	}

	timeout := time.Duration(downTimeOut) * time.Second
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()
	html, err := util.BookUrlContent(url_post, ua, []string{"body"}, submenu, sublink, url_info, url_post, "html", nil, ctx)
	if err != nil {
		fmt.Println("book error 1:", err.Error())
		Api.Msg = "book error 1:" + err.Error()
		api, _ := json.Marshal(Api)
		util.ApiWrite(&w, api)
		return
	}
	//fmt.Println(html)
	//p, s, i, j, err := util.UrlRange(url, end_url)

	doc, err := goquery.NewDocumentFromReader(strings.NewReader(html))
	if err != nil {
		fmt.Println("无法解析HTML文档:", err)
		Api.Msg = "无法解析HTML文档"
		api, _ := json.Marshal(Api)
		util.ApiWrite(&w, api)
		return
	}
	link_arr := make([]string, 0)
	link_res := make([]string, 0)
	link_prefix := ""
	if prefix != "" {
		link_prefix = prefix
	}
	doc.Find("a").Each(func(i int, s *goquery.Selection) {
		// 获取<a>标签的href属性
		href, _ := s.Attr("href")
		if strings.Contains(href, "javascript:") {
			return
		}
		if strings.Contains(url_post, href) {
			fmt.Println("skip 235", href)
			return
		}
		if !strings.Contains(href, link_prefix) {
			fmt.Println("skip 243", href)
			return
		}
		href = util.BookFullUrl(href, url_info, url_post)
		//相同跳过
		if strings.Contains(url_post, href) {
			fmt.Println("skip 248", href)
			return
		}
		fmt.Println("push", href)

		link_arr = append(link_arr, href)
	})
	//fmt.Println(link_arr)
	//return
	if sort == "true" || sort == "1" {
		link_arr = util.SliceReverse(link_arr)
	}

	if prefix == "" {
		link_prefix = util.UrlPrefix(link_arr)
	} else {
		link_prefix = prefix
	}

	if link_prefix == "" {
		Api.Msg = "无法解析目录"
		api, _ := json.Marshal(Api)
		util.ApiWrite(&w, api)
		return
	}
	fmt.Println("link_prefix", link_prefix)

	elMap := util.SliceCountElements(link_arr)
	//过滤链接
	for lk, url := range link_arr {
		if !strings.Contains(url, link_prefix) {
			continue
		}
		//
		if elMap[url] > 1 {
			fmt.Println("later", url, elMap[url])
			elMap[url] -= 1
			continue
		}
		//过界了
		if lk < start_num {
			continue
		}

		if lk > end_num && end_num > 0 {
			continue
		}
		//fmt.Println(url, elMap[url])
		link_res = append(link_res, url)
	}
	Api.Msg = name
	Api.Code = 0
	Api.Data = link_res
	api, _ := json.Marshal(Api)
	util.ApiWrite(&w, api)
}

func ComicUrlApi(w http.ResponseWriter, r *http.Request) {
	prefix := r.PostFormValue("prefix")
	RAW := r.PostFormValue("raw")
	tags := r.PostFormValue("tags")
	name := r.PostFormValue("name")
	url_post := r.PostFormValue("url")
	sublink := r.PostFormValue("sublink")
	PLACE := r.PostFormValue("place")
	proc := r.PostFormValue("proc")
	submenu := r.PostFormValue("submenu")
	prefix = strings.Trim(prefix, " ")
	down := r.PostFormValue("down")
	key := r.PostFormValue("key")

	if proc != "" {
		procn, err := strconv.Atoi(proc)
		if err != nil {
			maxProcces = 10
		}
		maxProcces = procn
		if maxProcces > 30 {
			maxProcces = 30
		}
	}

	root_path := ""
	filename := ""

	if tags == "" {
		tags = "h1,img@src"
	}
	tags_arr := strings.Split(tags, ",")
	if sublink == "" {
		sublink = "_"
	}
	dp := string(os.PathSeparator)
	root_path = os.Getenv("ROOT_PATH") + dp + "web" + dp
	comic_path := "output" + dp + "comic"
	fmt.Println(root_path + comic_path)
	if _, err := os.Stat(root_path + dp + comic_path); err != nil {
		if os.IsNotExist(err) {
			err = os.Mkdir(root_path+dp+comic_path, 0755)
			if err != nil {
				fmt.Println("创建文件夹失败1"+root_path+dp+comic_path, err)
			}
		} else {
			fmt.Println("创建文件夹失败2"+root_path+dp+comic_path, err)
		}
	}
	dir_path := root_path + comic_path + dp + name
	filename = comic_path + dp + name + dp + "index.comic"
	if _, err := os.Stat(dir_path); err != nil {
		if os.IsNotExist(err) {
			os.Mkdir(dir_path, 0755)
		}
	}

	out_path := root_path + filename
	Api := &structs.API{}
	url_info, err := neturl.Parse(url_post)
	if err != nil {
		fmt.Println("url error 1:", err.Error())
		Api.Msg = "url error 1:" + err.Error()
		api, _ := json.Marshal(Api)
		util.ApiWrite(&w, api)
		return
	}

	//下载
	comic, err := util.ComicUrlContent(url_post, tags_arr, submenu, sublink, url_info, url_post, "html", RAW, PLACE)
	comic.Index = key
	if err != nil {
		Api.Code = 1
		Api.Msg = err.Error()
		api, _ := json.Marshal(Api)
		util.ApiWrite(&w, api)
		return
	}
	jsond, _ := json.Marshal(comic)
	date := util.GetDate()
	//写入日志
	util.FilePutContent(root_path+comic_path+dp+date+".log", url_post+"\r\n"+tags+"\r\n"+sublink+"\r\n", true)

	//保存文件
	if down == "server" {
		ch := make(chan string, maxProcces)
		for _, val := range comic.Content {
			url := val
			go func() {
				type_names := strings.SplitN(path.Ext(url), "?", 2)
				finame := dir_path + dp + util.Md5(url) + type_names[0]
				util.ComicImgDown(url, finame)
				<-ch
				fmt.Println(url)
			}()
			ch <- val
		}
		//写入json
		util.FilePutContent(out_path, string(jsond)+"\r\n", key != "0")
	}
	Api.Code = 0
	Api.Msg = comic_path
	Api.Data = comic
	api, _ := json.Marshal(Api)
	util.ApiWrite(&w, api)
}

// 查询所有漫画
func ComicList(w http.ResponseWriter, r *http.Request) {
	util.ApiHeader(&w)
	name := r.PostFormValue("name")
	books := strings.Split(name, ";")
	Api := &structs.API{}
	if name == "" {
		Api.Code = 1
		api, _ := json.Marshal(Api)
		util.ApiWrite(&w, api)
		return
	}
	data := make(map[string]map[string]string)
	dp := string(os.PathSeparator)
	root_path := os.Getenv("ROOT_PATH") + dp + "web" + dp + "output" + dp + "comic"
	for _, book := range books {
		data[book] = make(map[string]string)
		fpath := root_path + dp + book
		info, err := os.Stat(fpath)
		if err != nil {
			data[book]["url"] = ""
			continue
		}
		data[book]["url"] = "/output/" + dp + "comic" + dp + book
		data[book]["size"] = strconv.Itoa(int(info.Size() / 1000))
		data[book]["time"] = util.FormatTime(info.ModTime())
	}
	Api.Data = data
	api, _ := json.Marshal(Api)
	util.ApiWrite(&w, api)
}

// 查询单个漫画
func ComicOne(w http.ResponseWriter, r *http.Request) {
	util.ApiHeader(&w)
	name := r.PostFormValue("name")

	Api := &structs.API{}
	if name == "" {
		Api.Code = 1
		Api.Msg = "无name"
		api, _ := json.Marshal(Api)
		util.ApiWrite(&w, api)
		return
	}

	dp := string(os.PathSeparator)
	root_path := os.Getenv("ROOT_PATH") + dp + "web" + dp
	comic_path := "output" + dp + "comic" + dp + name
	if _, err := os.Stat(root_path + comic_path); err != nil {
		Api.Code = 1
		Api.Msg = err.Error()
		api, _ := json.Marshal(Api)
		util.ApiWrite(&w, api)
		return
	}

	list, _ := util.ScanDir(root_path + comic_path)
	for k, v := range list {
		v = strings.ReplaceAll(v, root_path, "")
		list[k] = v
	}
	Api.Msg = comic_path
	Api.Data = list
	api, _ := json.Marshal(Api)
	util.ApiWrite(&w, api)
}
